/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package simhya.dataprocessing;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.*;
import java.util.Locale;
import simhya.utils.Debugger;

/**
 *
 * @author Luca
 */
public class Trajectory {
    private ArrayList<double []> data;
    private ArrayList<String> header;
    private ArrayList<Integer> toPrint;
    private int numberOfVars;
    private File outputFile;
    private ArrayList<String> additionalParameters;
    private ArrayList<Double> additionalParametersValue;


   
    public Trajectory(ArrayList<String> header) {
        this.header = (ArrayList<String>)header.clone();
        this.numberOfVars = header.size();
        this.header.add(0, "time");
        this.initialize();
    }

    private void initialize() {
        this.printAll();
        this.additionalParameters = new ArrayList();
        this.additionalParametersValue = new ArrayList();
        this.outputFile = null;
        this.data = new ArrayList();
    }

   


    public void printAll() {
        this.toPrint = new ArrayList();
        for (int i=0;i<this.header.size();i++)
            this.toPrint.add(i);   
    }

    public void printSubsetOfVars(ArrayList<String> varsToBePrinted) {
        this.toPrint = new ArrayList();
        this.toPrint.add(0);
        for (int i=1;i<=this.numberOfVars;i++)
            //first header is always time
            if (varsToBePrinted.contains(this.header.get(i)))
                this.toPrint.add(i);   
    }


    /**
     * Adds a  new point to the trajectory, at given time
     * @param time
     * @param values an arraylist of double values.
     */
    public void add(double time,double[] values) {
        //System.out.println("Adding a time point: " + time + "  " + Arrays.toString(values));

        double[] v = new double[values.length+1];
        v[0] = time;
        System.arraycopy(values,0, v, 1, values.length);
        //System.out.println("Time point is: " + Arrays.toString(v));
        data.add(v);
    }


    public void additionalParameter(String name, double value) {
        this.additionalParameters.add(name);
        this.additionalParametersValue.add(value);
        
    }

    public void setOutputFile(String filename) {
        this.outputFile = new File(filename);
    }

    public void setOutputFile(File file) {
        this.outputFile = file;
    }

    public void saveAsCSV(boolean append) {
        try {
            PrintStream p = new PrintStream(new FileOutputStream(this.outputFile,append));
            p.print(this.toString());
            p.close();
        }
        catch (IOException e) {
            System.out.println("Error: cannot save to file " + this.outputFile + "; " + e);
        }
    }


    public void toScreen() {
        for (Integer i : this.toPrint)
            System.out.print(String.format(Locale.US, "%20s", header.get(i)));
        System.out.println();
        for (double[] list : this.data) {
            for (Integer i : this.toPrint)
                System.out.print(String.format(Locale.US, "%20.6f", list[i]));
            System.out.println();
        }
    }


     public void debugToScreen() {

         System.out.println("Data points: " + data.size());
         for (Integer i : this.toPrint)
            System.out.print(String.format(Locale.US, "%20s", header.get(i)));
        System.out.println();
        for (double[] list : data) {
            System.out.println(Arrays.toString(list));
        }  
    }

    @Override
    public String toString() {

        //Debugger.put("Writing trajectory to string");

        String s = "";
        for (Integer i : this.toPrint)
            s += String.format(Locale.US, "%20s", header.get(i));
        s += "\n";    
        for (double[] list : this.data) {
            for (Integer i : this.toPrint)
                s += String.format(Locale.US, "%20.6f", list[i]);
            s += "\n";
        }
        return s;
    }



}
